var Direction = cc.Class({
    name: 'Direction',
    properties: {
        left: {
            default: 0,
            type: cc.Integer,
            range: [0, 100]
        },
        right: {
            default: 0,
            type: cc.Integer,
            range: [0, 100]
        },
        up: {
            default: 0,
            type: cc.Integer,
            range: [0, 100]
        },
        down: {
            default: 0,
            type: cc.Integer,
            range: [0, 100]
        },
    }
});

var Unit = cc.Class({
    name: 'Unit',
    properties: {
        id: {
            default: 0,
            type: cc.Integer,
            range: [0, 100],
            'tooltip': '唯一id，必须大于0'
        },

        button: {
            type: cc.Node,
            default: null,
            'tooltip': '控制摆动的按钮'
        },
        clickEvents: {
            default: [],
            type: cc.Component.EventHandler,
            'tooltip': '确定键按下后的事件回调'
        },
        swing: {
            default: true,
            'tooltip': '是否摆动按钮'
        },
        direction: {
            type: Direction,
            default: null,
            'tooltip': '方向控制手指移动'
        },
    }
});

var Arrow = cc.Enum({
    Up: 1,
    Down: 2,
    Left: 3,
    Right: 4,
});

cc.Class({
    extends: cc.Component,

    properties: {
        root: cc.Node,
        showFinger: {
            default: true,
            'tooltip': '是否显示手指'
        },
        curUnitId: {
            default: 0,
            type: cc.Integer,
            range: [0, 100],
            'tooltip': '初始手指光标位置id',
        },
        backEvents: {
            default: [],
            type: cc.Component.EventHandler,
            'tooltip': '返回键事件回调'
        },
        arrowEvents: {
            default: [],
            type: cc.Component.EventHandler,
            'tooltip': '方向键事件回调'
        },
        btnAudio: {
            default: true,
            'tooltip': '是否播放按钮移动，点击音效'
        },
        units: {
            type:[Unit],
            default:[],
            'tooltip': '手指光标移动控制'
        }
    },

    onLoad: function () {
        this.root.active = this.showFinger;
        this.setFingerPostion(this.curUnitId);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
    },

    onEnable:function() {
        this.runFingerAction();
    },

    onDisable:function() {
        this.stopFingerAction();
    },

    onKeyDown: function (event) {
        if (!this.node.active) {
            return;
        }
        event.stopPropagation();
        switch (event.keyCode) {
            case cc.macro.KEY.up:
            case cc.macro.KEY.dpadUp:
                this.onArrowClicked(Arrow.Up);
                break;
            case cc.macro.KEY.down:
            case cc.macro.KEY.dpadDown:
                this.onArrowClicked(Arrow.Down);
                break;
            case cc.macro.KEY.left:
            case cc.macro.KEY.dpadLeft:
                this.onArrowClicked(Arrow.Left);
                break;
            case cc.macro.KEY.right:
            case cc.macro.KEY.dpadRight:
                this.onArrowClicked(Arrow.Right);
                break;
            case cc.macro.KEY.enter:
            case cc.macro.KEY.dpadCenter:
                this.onEnterClicked();
                break;
            case cc.macro.KEY.escape:
            case cc.macro.KEY.back:
                this.onKeyBackClicked();
                break;
        }
    },

    setFingerPostion: function (id) {
        if (id == 0) {
            return;
        }
        this.stopFingerAction();
        this.units.map((unit) => {
            if (unit.id == id) {
                var wps = unit.button.parent.convertToWorldSpaceAR(unit.button.getPosition());
                var lps = this.node.parent.convertToNodeSpaceAR(wps);
                this.node.setPosition(lps);

                this.curUnit = unit;
                this.runFingerAction();
            }
        })
    },

    runFingerAction: function() {
        if (this.curUnit != null && this.curUnit.button != null && this.curUnit.swing) {
            if (this.curUnit.button.getComponent(cc.Animation) == null) {
                this.addSwingAnimation(this.curUnit.button);
            }
            else {
                this.curUnit.button.getComponent(cc.Animation).play('swing');
            }
        }
    },

    stopFingerAction: function() {
        if (this.curUnit != null && this.curUnit.button != null && this.curUnit.swing) {
            this.curUnit.button.getComponent(cc.Animation).stop('swing');
            this.curUnit.button.y = 0;
        }
    },

    addSwingAnimation: function(node) {
        var ani = node.addComponent(cc.Animation);
        cc.loader.loadRes('animation/swing', (err, res) =>{
            if (err) {
                cc.log('load swing animation error [' + err + ']');
                return;
            }
            ani.addClip(res);
            ani.play(res.name);
        });
    },

    onArrowClicked: function (arrow) {
        if (this.curUnit != null) {
            var nextUnitId = 0;
            switch (arrow) {
                case Arrow.Up:
                    nextUnitId = this.curUnit.direction.up;
                    break;
                case Arrow.Down:
                    nextUnitId = this.curUnit.direction.down;
                    break;
                case Arrow.Left:
                    nextUnitId = this.curUnit.direction.left;
                    break;
                case Arrow.Right:
                    nextUnitId = this.curUnit.direction.right;
                    break;
            }
            if (nextUnitId != 0) {
                this.setFingerPostion(nextUnitId);
                this.playBtnEffect("audio/BtnMove");
            }
        }
        cc.Component.EventHandler.emitEvents(this.arrowEvents, arrow);
    },

    onEnterClicked: function () {
        if (this.curUnit != null && this.curUnit.clickEvents.length != 0) {
            cc.Component.EventHandler.emitEvents(this.curUnit.clickEvents,
                this.curUnit.clickEvents.customEventData);
            this.playBtnEffect("audio/BtnClick");
        }
    },

    onKeyBackClicked: function () {
        if (this.backEvents.length != 0) {
            cc.Component.EventHandler.emitEvents(this.backEvents);
        }
    },

    playBtnEffect: function(url) {
        if (this.btnAudio) {
            cc.loader.loadRes(url, cc.AudioClip, function (err, clip) {
                cc.audioEngine.playEffect(clip, false);
            });
        }
    }

});